package com.falcon.file.storage.impl;

import com.falcon.file.config.FileConfig;
import com.falcon.file.enums.FileTypeEnum;
import com.falcon.file.storage.IFileStorage;
import com.swan.core.exception.SwanBaseException;
import com.swan.core.utils.time.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

/**
 * @author zongf
 * @since 2023-05-25
 **/
public class FileDiskStorage implements IFileStorage {

    @Autowired
    private FileConfig fileConfig;

    @Override
    public String write(MultipartFile file) {
        String timestamp = DateUtil.format(new Date(), "yyyyMMddHHmmssSSS");

        // 获取文件扩展名和文件类型
        String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
        FileTypeEnum fileTypeEnum = FileTypeEnum.OfExtension(extension);

        // 获取文件相对路径
        String relativePath = String.format("%s/%s-%s", fileTypeEnum.getCode(), timestamp, file.getOriginalFilename());

        // 获取文件绝对路径
        String absolutePath = fileConfig.getDiskPath() + "/" + relativePath;

        try {
            File diskFile = new File(absolutePath);
            // 如果父目录不存在
            if (!diskFile.getParentFile().exists()) {
                diskFile.getParentFile().mkdirs();
            }
            file.transferTo(diskFile);
        } catch (IOException e) {
            throw new SwanBaseException();
        }

        return relativePath;
    }

    @Override
    public void read(String storageId, OutputStream os) {

        String absolutePath = fileConfig.getDiskPath() + "/" + storageId;

        File file = new File(absolutePath);
        if (!file.exists()) {
            throw new SwanBaseException(-1, "文件不存在");
        }
        if (!file.isDirectory()) {
            throw new SwanBaseException(-1, "文件类型不允许下载");
        }

        try {
            FileInputStream fis = new FileInputStream(file);

            byte[] bytes = new byte[1024];

            int length;
            while ((length = fis.read(bytes)) > 0) {
                os.write(bytes, 0, length);
            }

        } catch (Exception e) {
            throw new SwanBaseException();
        }
    }
}
